#pragma once

#include <string>
#include <jsoncpp/json/json.h>

const std::string blank_space_sep = " ";
const std::string protocol_sep = "\n";

//"len\n" + msg + "\n"
bool Encode(const std::string& msg, std::string* package)
{
    *package += std::to_string(msg.size());
    *package += protocol_sep;
    *package += msg;
    *package += protocol_sep;
    return true;
}

bool Decode(const std::string& package, std::string* msg)
{
    int pos = package.find(protocol_sep, 0);
    if(pos == std::string::npos) { return false; }
    int len = std::stoi(package.substr(0, pos));
    if(package.substr(pos + 1).size() - 1 != len) {
        return false;
    }
    *msg = package.substr(pos + 1, len);
    return true;
}
//这个重载用来判断当前读取的报文是否完整合法
bool Decode(const std::string& package)
{
    int pos = package.find(protocol_sep, 0);
    if(pos == std::string::npos) { return false; }
    int len = std::stoi(package.substr(0, pos));
    if(package.substr(pos + 1).size() - 1 != len) {
        return false;
    }
    return true;
}

class Request
{
public:
    Request(int x, int y, char op)
        :_x(x), _y(y), _op(op)
    { }

    Request() { }

    //"x op y"
    std::string Serialization()
    {
#ifdef MYCODE
        std::string msg;
        msg += std::to_string(_x);
        msg += blank_space_sep;
        msg += _op;
        msg += blank_space_sep;
        msg += std::to_string(_y);
        return msg;
#else
    Json::Value root;
    root["x"] = _x;
    root["y"] = _y;
    root["op"] = _op;
    Json::FastWriter w;
    return w.write(root);
#endif
    }

    bool Deserialization(std::string& msg)
    {
#ifdef MYCODE
        int left = msg.find(blank_space_sep, 0);
        _x = std::stoi(msg.substr(0, left));
        int right = msg.rfind(blank_space_sep);
        _y = std::stoi(msg.substr(right + 1));
        if(right - left != 2) {
            return false;
        }
        _op = msg[left + 1];
        return true;
#else
        Json::Value root;
        Json::Reader r;
        r.parse(msg, root);
        _x = root["x"].asInt();
        _y = root["y"].asInt();
        _op = root["op"].asInt();
        return true;
#endif
    }

public:
    int _x;
    int _y;
    char _op;
};

class Response
{
public:
    Response()
        :_result(0), _code(0)
    { }

    //"code result"
    std::string Serialization()
    {
#ifdef MYCODE
        std::string msg;
        msg += std::to_string(_code);
        msg += blank_space_sep;
        msg += std::to_string(_result);
        return msg;
#else
        Json::Value root;
        root["code"] = _code;
        root["result"] = _result;
        Json::FastWriter w;
        return w.write(root);
#endif
    }

    bool Deserialization(std::string& msg)
    {
#ifdef MYCODE
        int pos = msg.find(blank_space_sep, 0);
        _code = std::stoi(msg.substr(0, pos));
        _result = std::stoi(msg.substr(pos + 1));
        return true;
#else
        Json::Value root;
        Json::Reader r;
        r.parse(msg, root);
        _result = root["result"].asInt();
        _code = root["code"].asInt();
        return true;
#endif
    }

public:
    int _result;
    int _code;
};